home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / BTNGO.ZIP / BTNGOC.ZIP / LONCH.CPP < prev    next >
C/C++ Source or Header  |  1993-09-28  |  32KB  |  750 lines

  1. // DEBUG_SCREENS for message-box progress indicators
  2. // FAKE_LAUNCHES for message boxes instead of actual launches
  3. // SHOW_LAUNCHDATA for quick display just before prog launch -- works only if FAKE_LAUNCHES *not* specified
  4. // CHANGE_DIR to change directory to entry's default before launch attempted
  5. #include<windows.h>
  6. #include<commdlg.h>
  7. #include"wstring.hpp"
  8. #include"itemdata.hpp"
  9. #include"resource.h"
  10. #include"ini.hpp"
  11. #include<string.h>
  12. #include<ctype.h>
  13. #ifndef FAKE_LAUNCHES
  14. #include<direct.h>
  15. #endif
  16.  
  17. #define IDM_GETSTARTED 1
  18.  
  19. #define IDM_ABOUT 1001
  20. #define IDM_HELP 1002
  21. #define IDM_ONTOP 1003
  22. #define IDM_MYSYSCOMMANDS 1010
  23.  
  24. #define BUTTON_WIDTH (icon_width+5)
  25.  
  26. IniFile ini;
  27. GroupFile gf;
  28. #ifdef DEBUG_SCREENS
  29. WinMessageString screen;
  30. #endif
  31. WinMessageString errscreen;
  32. const int SCRATCH=256;
  33. unsigned int winver; // windows version
  34. char scratch[SCRATCH+1];
  35. static char WindowTitle[256];
  36. static char szFile[256]; // filename for .GRP file
  37. static HWND main_hwnd=NULL;
  38. static HINSTANCE main_hinst=NULL;
  39. static char AppTitle[]="ButtonGo";
  40. static char AppClassName[]="ButtonGoDeurbrouckClass";
  41. static char copyright[]=
  42.     "BTNGO.EXE 1.0\n"
  43.     "Program Launching Utility\n"
  44.     "Copyright ⌐ 1993 John Deurbrouck\n\n"
  45.     "First published in PC Magazine September 28, 1993\n";
  46. static char helpstring[]=
  47.     "BTNGO conveniently displays the icons from any Program Manager group "
  48.     "and allows you to launch them with a single mouse click.\n\n"
  49.     "If started with a .GRP file specified on the command line, BTNGO can operate under "
  50.     "Windows 3.0 and later. Otherwise, BTNGO requires COMMDLG.DLL to run under 3.0.\n\n"
  51.     "See PC Magazine, September 28, 1993 (Vol. 12 No. 15) for more details. Support is also available "
  52.     "on ZiffNet. From Compuserve, GO ZNT:UTILFORUM.";
  53. static char too_many_icons[]=
  54.     "The group you have loaded has too many icons to display, "
  55.     "so some of your icons may not be visible. "
  56.     "No damage has occurred, and you may use the icons you can see.\n\n"
  57.     "You can fix this by removing less-important items from the group, or by "
  58.     "creating another group file and moving some icons from this group "
  59.     "to the new one.";
  60. static LPSTR command_line_pointer;
  61. static HMENU gm=NULL; // system menu for main window
  62. static HBITMAP hbmUp=NULL,hbmDown=NULL,hbmNow=NULL; // for painting the main window
  63. static unsigned int max_index_added=0;
  64. static int show_parameter; // for call to ShowWindow, parm passed into WinMain
  65. static int actual_buttons=0; // number buttons on button bar
  66. static int icon_height,icon_width,bitmap_width,bitmap_height;
  67. static int mouse_down=0,mouse_button_number=-1,ok_to_launch; // used to drive mouse handling
  68. static int should_save_position_data=0,got_position_data,best_ontop=1,best_x,best_y; // used for .INI file handling
  69.  
  70. void GetFilenameFromCmdLine(LPSTR cmdline,char *winpath,char *filename);
  71. long FAR PASCAL __export MainWndProc(HWND,UINT,UINT,LONG);
  72. int GetFileDataLoaded(LPSTR cmdline);
  73. int CreateBitmaps(void);
  74. int button_mouse_is_in(LONG lParam);
  75. void restore_mouse_normalcy(void);
  76. void get_right_bitmap(HDC hdc);
  77. #ifdef FAKE_LAUNCHES
  78. char *show_exe_data(int offset);
  79. #else
  80. void start_program(int offset);
  81. #endif
  82.  
  83. int PASCAL WinMain(HINSTANCE hinstCurrent,HINSTANCE hinstPrevious,LPSTR lpszCmdLine,int nCmdShow){
  84.     if(!hinstPrevious){
  85.         WNDCLASS wc;
  86.         wc.style=CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS;
  87.         wc.lpfnWndProc=MainWndProc;
  88.         wc.cbClsExtra=0;
  89.         wc.cbWndExtra=0;
  90.         wc.hInstance=hinstCurrent;
  91.         wc.hIcon=LoadIcon(hinstCurrent,MAKEINTRESOURCE(IDI_APPICON));
  92.         wc.hCursor=LoadCursor(NULL,IDC_ARROW);
  93.         wc.hbrBackground=NULL;
  94.         wc.lpszMenuName=NULL;
  95.         wc.lpszClassName=AppClassName;
  96.         RegisterClass(&wc);
  97.     }
  98.     {
  99.         DWORD ver=GetVersion();
  100.         winver=LOBYTE(LOWORD(ver));
  101.         winver<<=8;
  102.         winver|=HIBYTE(LOWORD(ver));
  103.     }
  104.     command_line_pointer=lpszCmdLine;
  105.     main_hinst=hinstCurrent;
  106.     show_parameter=nCmdShow;
  107.     ini.set_instance(hinstCurrent);
  108.     main_hwnd=CreateWindow(AppClassName,AppTitle,
  109.                 WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX,
  110.                 CW_USEDEFAULT,CW_USEDEFAULT, // X,Y coords
  111.                 CW_USEDEFAULT,CW_USEDEFAULT, // x,y extents
  112.                 HWND_DESKTOP,NULL,hinstCurrent,NULL);
  113.     #ifdef DEBUG_SCREENS
  114.     screen.SetHwndParent(main_hwnd);
  115.     #endif
  116.     errscreen.SetHwndParent(main_hwnd);
  117.     MSG msg;
  118.     while(GetMessage(&msg,NULL,0,0)){
  119.         TranslateMessage(&msg);
  120.         DispatchMessage(&msg);
  121.     }
  122.     return msg.wParam;
  123. }
  124.  
  125. static void GetFilenameFromCmdLine(LPSTR cmdline,char *winpath,char *filename){
  126.     LPSTR string_start;
  127.     int got_pathchars=0,got_goodchars=0,got_whitespace=0;
  128.     if(cmdline==NULL)return;
  129.     while(*cmdline){  // scan, find filename start, look for '\\' and ':'
  130.         if(isgraph(*cmdline)){
  131.             if(got_whitespace){
  132.                 errscreen<<"Too many command line arguments";
  133.                 errscreen.show();
  134.                 return;
  135.             }
  136.             if(!got_goodchars){
  137.                 got_goodchars=1;
  138.                 string_start=cmdline;
  139.             }
  140.             if(*cmdline=='\\'||*cmdline==':')got_pathchars=1;
  141.             if(*cmdline=='*'||*cmdline=='?'){
  142.                 errscreen<<"Can't use wildcards in command line arguments";
  143.                 errscreen.show();
  144.                 return;
  145.             }
  146.         }
  147.         else{
  148.             if(got_goodchars)got_whitespace=1;
  149.         }
  150.         cmdline++;
  151.     }
  152.     if(!got_goodchars)return; // no filename
  153.     if(!got_pathchars){  // insert Windows dir, normal place for .GRP
  154.         lstrcpy(filename,winpath);
  155.         cmdline=filename;
  156.         while(*cmdline)cmdline++;
  157.         if(cmdline[-1]!='\\'){*cmdline++='\\';*cmdline=0;}
  158.         lstrcat(filename,string_start);
  159.     }
  160.     else lstrcpy(filename,string_start);
  161.     // now scan off any whitespace at end of filename
  162.     cmdline=filename;
  163.     while(*cmdline)cmdline++;
  164.     cmdline--;
  165.     while(!isgraph(*cmdline))*cmdline--=0;
  166. }
  167. long FAR PASCAL __export MainWndProc(HWND hwnd,UINT message,UINT wParam,LONG lParam){
  168.     switch(message){
  169.     case WM_CREATE:
  170.         PostMessage(hwnd,WM_COMMAND,IDM_GETSTARTED,0L);
  171.         return 0;
  172.     case WM_COMMAND:
  173.         switch(wParam){
  174.         case IDM_GETSTARTED:
  175.             gm=GetSystemMenu(main_hwnd,FALSE);
  176.             DeleteMenu(gm,SC_SIZE,MF_BYCOMMAND);
  177.             DeleteMenu(gm,SC_MAXIMIZE,MF_BYCOMMAND);
  178.             AppendMenu(gm,MF_SEPARATOR,0,NULL);
  179.             if(winver>=0x30A)AppendMenu(gm,MF_STRING,IDM_ONTOP,"Always on Top");
  180.             AppendMenu(gm,MF_STRING,IDM_ABOUT,"About...");
  181.             AppendMenu(gm,MF_STRING,IDM_HELP,"Help...");
  182.             if(!GetFileDataLoaded(command_line_pointer)||
  183.             !gf.get_icon_dimensions(icon_height,icon_width)||
  184.             !CreateBitmaps()){
  185.                 PostMessage(hwnd,WM_DESTROY,0,0L);
  186.                 return 0;
  187.             }
  188.             if(gf.get_group_name()!=NULL){
  189.                 wsprintf(WindowTitle,"%s - %s",(LPSTR)AppTitle,gf.get_group_name());
  190.             }
  191.             else lstrcpy(WindowTitle,AppTitle);
  192.             gf.done_with_bitmaps();
  193.             SetWindowText(hwnd,WindowTitle);
  194.             should_save_position_data=1;
  195.             got_position_data=ini.get_screen_numbers(szFile,best_x,best_y,best_ontop);
  196.             if(winver>=0x30A&&best_ontop)PostMessage(hwnd,WM_SYSCOMMAND,IDM_ONTOP,0L);
  197.             int window_width=GetSystemMetrics(SM_CXBORDER)*2+bitmap_width;
  198.             int window_height=GetSystemMetrics(SM_CYCAPTION)+bitmap_height+GetSystemMetrics(SM_CYBORDER);
  199.             /*
  200.                 ok, someone changing from 1024x768 to 800x600 drivers might 'lose' the
  201.                 window so let's be sure the window's at least partially onscreen.
  202.                 if at least one pixel of the caption area is onscreen, the window
  203.                 can be grabbed and moved, so let's check for that
  204.             */
  205.             if(got_position_data)for(;;){
  206.                 got_position_data=0; // so can break on errors
  207.                 int capt_left=best_x+G